/*
 * usageHelper.cpp
 *
 *  Created on: Sep 17, 2011
 *      Author: shaohong
 */

#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include <string>
#include <sys/time.h>

#include "usageHelper.h"
#include "AppLogger.h"
#include "HttpHelper.h"
#include <cstring>


using namespace std;

static const char *optString = "+m:u:c:h?";

static AppLogger * logger = AppLogger::getInstance("UsageHelper");


struct StreamerConfig globalConfig;
struct StreamerStats globalStreamerStats;

/*
 * Print the usage information to the user
 */
void printUsage(void) {
	cout
			<< "======\n"
			<< "usage:\n"
			<< "======\n"
			<< "	radioStreamer -u http_url<:port> [-p local_tcp_port] -c audioPlayerAddress:port <audioPlayerAddress:port>"
			<< endl
			<< endl
			<< "	-u Specify the URL of the radio station HTML page. "
					"The optional port specify the http listening port of the remote server. default to 80 if not specified."
			<< endl
			<< endl
			<< "	-c can have a list of audio player's IP and port addresses. These values are space separated"
			<< endl
			<< "	-m Specify the mode the programm us running. 1 for console based radio streamer and 2 for SIP based radio station."
			<< endl;
}

static void initStreamerConfig(StreamerConfig* streamerConfig){
	//initialize the configuration data
	streamerConfig->localTcpPort = 0;
	memset(streamerConfig->radioStationURL, 0, sizeof(streamerConfig->radioStationURL));

	memset(streamerConfig->recipientList, 0, sizeof(streamerConfig->recipientList));

	streamerConfig->programMode = assignment1Mode;
}

bool isSipServerEnable(StreamerConfig config){
	return (assignment2Mode == config.programMode);
}

int parseCommandLine(int argc, char *argv[], StreamerConfig* streamerConfig) {

	initStreamerConfig(streamerConfig);

	// check the argument list

	// if argument list is empty, print the usage.
	if (1 == argc) {
		printUsage();

		exit(EXIT_FAILURE);
	}

	/* Process the arguments with getopt(), then
	 * populate streamerConfig.
	 */
	int opt = getopt(argc, argv, optString);
	while (opt != -1) {

		switch (opt) {
		case 'u':
			if (NULL != optarg) {
				// argument following -u option. The URL of remote server from where we can see links to playlist file
				strcpy(streamerConfig->radioStationURL, optarg);
			}
			break;

		case 'p':
			if (NULL != optarg) {
				streamerConfig->localTcpPort = atoi(optarg);
			}
			break;

		case 'm':
			if (NULL != optarg) {
				streamerConfig->programMode = atoi(optarg);
			}
			break;

		case 'c':
			if (NULL != optarg) {
//				fprintf(stderr, "-c option:%s\n", optarg);
				//argument following -c option gives the RTP client address
				string clientAddressStr = string(optarg);
				size_t seperatorPos = clientAddressStr.find(':', 0);

				if (seperatorPos == string::npos) {
					fprintf(stderr, "invalid -c option: %s", optarg);
					logger->error("invalid -c option %s", optarg);
					exit(-1);
				}

				strncpy(streamerConfig->recipientList, optarg, sizeof(streamerConfig->recipientList) - 1);

			}
			break;

		case 'h':
		case '?':
			printUsage();
			exit(EXIT_FAILURE);
			break;

		default:
			printUsage();

			exit(EXIT_FAILURE);
		}

		opt = getopt(argc, argv, optString);
	}

	if (optind < argc) {
		// additional "client addresses" are from argv[optind] to argv[argc-1]
	}

	return 0;
}

void displayStreamerConfig(StreamerConfig streamerConfig) {
	logger->debug("streamerConfig [ radioStationURL = %s, "
			"mode = %d, streamerConfig.recipientList = %s]",
			streamerConfig.radioStationURL, streamerConfig.programMode,
			streamerConfig.recipientList);
}

/**
 * initialize the statistics of the global stats
 */
void initStreamerStats(StreamerStats * streamerStats) {
	memset(streamerStats, 0, sizeof(StreamerStats));
}

void saveStreamerStartTime(StreamerStats * streamerStats){

	char buffer[11];
	time_t t;
	time(&t);
	strftime(buffer, sizeof(buffer), "%X", localtime(&t));
	struct timeval tv;
	gettimeofday(&tv, 0);
	sprintf(streamerStats->startTime, "%s.%03ld", buffer, (long) tv.tv_usec / 1000);

	streamerStats->tStart = tv;

}

void saveStreamerEndTime(StreamerStats * streamerStats){
	char buffer[11];
	time_t t;
	time(&t);
	strftime(buffer, sizeof(buffer), "%X", localtime(&t));
	struct timeval tv;
	gettimeofday(&tv, 0);
	sprintf(streamerStats->endTime, "%s.%03ld", buffer, (long) tv.tv_usec / 1000);

	streamerStats->tEnd = tv;
}

void incrementMp3FramesReceived(StreamerStats * streamerStats){
	streamerStats->mp3FramesReceived ++;
}

void incrementPcmFrameSent(StreamerStats * streamerStats) {
	streamerStats->pcmFramesSent ++;
}

